{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Logistic 回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 首先 import 必要的模块\n",
    "import pandas as pd \n",
    "import numpy as np\n",
    "\n",
    "# 将数据分割训练数据与测试数据\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "# 评价指标为logloss\n",
    "from sklearn.metrics import log_loss  \n",
    "\n",
    "from matplotlib import pyplot\n",
    "import seaborn as sns\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取数据&数据探索"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>6</td>\n",
       "      <td>148.0</td>\n",
       "      <td>72.0</td>\n",
       "      <td>35.0</td>\n",
       "      <td>125.0</td>\n",
       "      <td>33.6</td>\n",
       "      <td>0.627</td>\n",
       "      <td>50</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>85.0</td>\n",
       "      <td>66.0</td>\n",
       "      <td>29.0</td>\n",
       "      <td>125.0</td>\n",
       "      <td>26.6</td>\n",
       "      <td>0.351</td>\n",
       "      <td>31</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8</td>\n",
       "      <td>183.0</td>\n",
       "      <td>64.0</td>\n",
       "      <td>29.0</td>\n",
       "      <td>125.0</td>\n",
       "      <td>23.3</td>\n",
       "      <td>0.672</td>\n",
       "      <td>32</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1</td>\n",
       "      <td>89.0</td>\n",
       "      <td>66.0</td>\n",
       "      <td>23.0</td>\n",
       "      <td>94.0</td>\n",
       "      <td>28.1</td>\n",
       "      <td>0.167</td>\n",
       "      <td>21</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>137.0</td>\n",
       "      <td>40.0</td>\n",
       "      <td>35.0</td>\n",
       "      <td>168.0</td>\n",
       "      <td>43.1</td>\n",
       "      <td>2.288</td>\n",
       "      <td>33</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \\\n",
       "0            6    148.0           72.0           35.0    125.0  33.6   \n",
       "1            1     85.0           66.0           29.0    125.0  26.6   \n",
       "2            8    183.0           64.0           29.0    125.0  23.3   \n",
       "3            1     89.0           66.0           23.0     94.0  28.1   \n",
       "4            0    137.0           40.0           35.0    168.0  43.1   \n",
       "\n",
       "   DiabetesPedigreeFunction  Age  Outcome  \n",
       "0                     0.627   50        1  \n",
       "1                     0.351   31        0  \n",
       "2                     0.672   32        1  \n",
       "3                     0.167   21        0  \n",
       "4                     2.288   33        1  "
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读取数据\n",
    "# path to where the data lies\n",
    "train = pd.read_csv(\"DP_diabetes.csv\")\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 768 entries, 0 to 767\n",
      "Data columns (total 9 columns):\n",
      "Pregnancies                 768 non-null int64\n",
      "Glucose                     768 non-null float64\n",
      "BloodPressure               768 non-null float64\n",
      "SkinThickness               768 non-null float64\n",
      "Insulin                     768 non-null float64\n",
      "BMI                         768 non-null float64\n",
      "DiabetesPedigreeFunction    768 non-null float64\n",
      "Age                         768 non-null int64\n",
      "Outcome                     768 non-null int64\n",
      "dtypes: float64(6), int64(3)\n",
      "memory usage: 54.1 KB\n"
     ]
    }
   ],
   "source": [
    "train.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pregnancies</th>\n",
       "      <th>Glucose</th>\n",
       "      <th>BloodPressure</th>\n",
       "      <th>SkinThickness</th>\n",
       "      <th>Insulin</th>\n",
       "      <th>BMI</th>\n",
       "      <th>DiabetesPedigreeFunction</th>\n",
       "      <th>Age</th>\n",
       "      <th>Outcome</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "      <td>768.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>3.845052</td>\n",
       "      <td>121.656250</td>\n",
       "      <td>72.386719</td>\n",
       "      <td>29.108073</td>\n",
       "      <td>140.671875</td>\n",
       "      <td>32.455208</td>\n",
       "      <td>0.471876</td>\n",
       "      <td>33.240885</td>\n",
       "      <td>0.348958</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>3.369578</td>\n",
       "      <td>30.438286</td>\n",
       "      <td>12.096642</td>\n",
       "      <td>8.791221</td>\n",
       "      <td>86.383060</td>\n",
       "      <td>6.875177</td>\n",
       "      <td>0.331329</td>\n",
       "      <td>11.760232</td>\n",
       "      <td>0.476951</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>44.000000</td>\n",
       "      <td>24.000000</td>\n",
       "      <td>7.000000</td>\n",
       "      <td>14.000000</td>\n",
       "      <td>18.200000</td>\n",
       "      <td>0.078000</td>\n",
       "      <td>21.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>99.750000</td>\n",
       "      <td>64.000000</td>\n",
       "      <td>25.000000</td>\n",
       "      <td>121.500000</td>\n",
       "      <td>27.500000</td>\n",
       "      <td>0.243750</td>\n",
       "      <td>24.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>3.000000</td>\n",
       "      <td>117.000000</td>\n",
       "      <td>72.000000</td>\n",
       "      <td>29.000000</td>\n",
       "      <td>125.000000</td>\n",
       "      <td>32.300000</td>\n",
       "      <td>0.372500</td>\n",
       "      <td>29.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>6.000000</td>\n",
       "      <td>140.250000</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>32.000000</td>\n",
       "      <td>127.250000</td>\n",
       "      <td>36.600000</td>\n",
       "      <td>0.626250</td>\n",
       "      <td>41.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>17.000000</td>\n",
       "      <td>199.000000</td>\n",
       "      <td>122.000000</td>\n",
       "      <td>99.000000</td>\n",
       "      <td>846.000000</td>\n",
       "      <td>67.100000</td>\n",
       "      <td>2.420000</td>\n",
       "      <td>81.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       Pregnancies     Glucose  BloodPressure  SkinThickness     Insulin  \\\n",
       "count   768.000000  768.000000     768.000000     768.000000  768.000000   \n",
       "mean      3.845052  121.656250      72.386719      29.108073  140.671875   \n",
       "std       3.369578   30.438286      12.096642       8.791221   86.383060   \n",
       "min       0.000000   44.000000      24.000000       7.000000   14.000000   \n",
       "25%       1.000000   99.750000      64.000000      25.000000  121.500000   \n",
       "50%       3.000000  117.000000      72.000000      29.000000  125.000000   \n",
       "75%       6.000000  140.250000      80.000000      32.000000  127.250000   \n",
       "max      17.000000  199.000000     122.000000      99.000000  846.000000   \n",
       "\n",
       "              BMI  DiabetesPedigreeFunction         Age     Outcome  \n",
       "count  768.000000                768.000000  768.000000  768.000000  \n",
       "mean    32.455208                  0.471876   33.240885    0.348958  \n",
       "std      6.875177                  0.331329   11.760232    0.476951  \n",
       "min     18.200000                  0.078000   21.000000    0.000000  \n",
       "25%     27.500000                  0.243750   24.000000    0.000000  \n",
       "50%     32.300000                  0.372500   29.000000    0.000000  \n",
       "75%     36.600000                  0.626250   41.000000    1.000000  \n",
       "max     67.100000                  2.420000   81.000000    1.000000  "
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "## 各属性的统计特性\n",
    "train.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a163e3470>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Target 分布，看看各类样本分布是否均衡\n",
    "sns.countplot(train.Outcome);\n",
    "pyplot.xlabel('Outcome');\n",
    "pyplot.ylabel('Number of occurrences');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 特征编码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "y = train['Outcome']\n",
    "X = train.drop('Outcome',axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 随机采样20%的数据构建测试样本，其余作为训练样本\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=33, test_size=0.2, stratify=y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((614, 8), (154, 8))"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape, X_test.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 数据标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "# 初始化特征的标准化器\n",
    "ss_X = StandardScaler()\n",
    "\n",
    "# 分别对训练和测试数据的特征进行标准化处理\n",
    "X_train = ss_X.fit_transform(X_train)\n",
    "#X_test = ss_X.transform(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1 缺省的Logistic回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "lr= LogisticRegression()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "logloss of each fold is:  [ 0.52812204  0.56362801  0.51840887  0.43573494  0.42967303]\n",
      "cv logloss is: 0.4951133782\n"
     ]
    }
   ],
   "source": [
    "# 交叉验证用于评估模型性能和进行参数调优（模型选择）\n",
    "#分类任务中交叉验证缺省是采用StratifiedKFold\n",
    "from sklearn.cross_validation import cross_val_score\n",
    "loss = cross_val_score(lr, X_train, y_train, cv=5, scoring='neg_log_loss')\n",
    "print('logloss of each fold is: ',-loss)\n",
    "print('cv logloss is:', -loss.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2 正则化的Logistic回归"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=5, error_score='raise',\n",
       "       estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,\n",
       "          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
       "          verbose=0, warm_start=False),\n",
       "       fit_params=None, iid=True, n_jobs=1,\n",
       "       param_grid={'penalty': ['l1', 'l2'], 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score='warn',\n",
       "       scoring='neg_log_loss', verbose=0)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#需要调优的参数\n",
    "# 请尝试将L1正则和L2正则分开，并配合合适的优化求解算法（slover）\n",
    "#tuned_parameters = {'penalty':['l1','l2'],\n",
    "#                   'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "#                   }\n",
    "penaltys = ['l1','l2']\n",
    "Cs = [0.001, 0.01, 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(penalty = penaltys, C = Cs)\n",
    "\n",
    "# GridSearchCV，neg_log_loss做评价指标\n",
    "lr_penalty= LogisticRegression()\n",
    "grid= GridSearchCV(lr_penalty, tuned_parameters,cv=5, scoring='neg_log_loss')\n",
    "grid.fit(X_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('mean_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('split0_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('split1_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('split2_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('split3_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('split4_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('std_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'mean_fit_time': array([ 0.00145864,  0.00094953,  0.00092111,  0.0008348 ,  0.00086336,\n",
       "         0.00096526,  0.00110178,  0.00090647,  0.00095453,  0.00103054,\n",
       "         0.00109534,  0.00107737,  0.00110917,  0.00106893]),\n",
       " 'mean_score_time': array([ 0.00226078,  0.00101728,  0.00068364,  0.00080638,  0.0006813 ,\n",
       "         0.00087528,  0.00082803,  0.00084434,  0.00071764,  0.00079007,\n",
       "         0.00082994,  0.00096707,  0.00103335,  0.00106983]),\n",
       " 'mean_test_score': array([-0.69314718, -0.64135116, -0.67369059, -0.53512497, -0.49728356,\n",
       "        -0.49445768, -0.49493812, -0.49521996, -0.49583701, -0.49588065,\n",
       "        -0.49594917, -0.49595729, -0.49596014, -0.49596507]),\n",
       " 'mean_train_score': array([-0.69314718, -0.6393169 , -0.66967204, -0.52554211, -0.48077798,\n",
       "        -0.47423485, -0.47040508, -0.47025153, -0.47018328, -0.4701817 ,\n",
       "        -0.47018096, -0.47018094, -0.47018093, -0.47018093]),\n",
       " 'param_C': masked_array(data = [0.001 0.001 0.01 0.01 0.1 0.1 1 1 10 10 100 100 1000 1000],\n",
       "              mask = [False False False False False False False False False False False False\n",
       "  False False],\n",
       "        fill_value = ?),\n",
       " 'param_penalty': masked_array(data = ['l1' 'l2' 'l1' 'l2' 'l1' 'l2' 'l1' 'l2' 'l1' 'l2' 'l1' 'l2' 'l1' 'l2'],\n",
       "              mask = [False False False False False False False False False False False False\n",
       "  False False],\n",
       "        fill_value = ?),\n",
       " 'params': [{'C': 0.001, 'penalty': 'l1'},\n",
       "  {'C': 0.001, 'penalty': 'l2'},\n",
       "  {'C': 0.01, 'penalty': 'l1'},\n",
       "  {'C': 0.01, 'penalty': 'l2'},\n",
       "  {'C': 0.1, 'penalty': 'l1'},\n",
       "  {'C': 0.1, 'penalty': 'l2'},\n",
       "  {'C': 1, 'penalty': 'l1'},\n",
       "  {'C': 1, 'penalty': 'l2'},\n",
       "  {'C': 10, 'penalty': 'l1'},\n",
       "  {'C': 10, 'penalty': 'l2'},\n",
       "  {'C': 100, 'penalty': 'l1'},\n",
       "  {'C': 100, 'penalty': 'l2'},\n",
       "  {'C': 1000, 'penalty': 'l1'},\n",
       "  {'C': 1000, 'penalty': 'l2'}],\n",
       " 'rank_test_score': array([14, 12, 13, 11, 10,  1,  2,  3,  4,  5,  6,  7,  8,  9], dtype=int32),\n",
       " 'split0_test_score': array([-0.69314718, -0.64024158, -0.66929698, -0.53743624, -0.50977957,\n",
       "        -0.51621024, -0.52527159, -0.52812204, -0.5302679 , -0.53056708,\n",
       "        -0.53079882, -0.53083382, -0.53084861, -0.53086074]),\n",
       " 'split0_train_score': array([-0.69314718, -0.63938293, -0.66835896, -0.5217155 , -0.47310947,\n",
       "        -0.46519395, -0.4606101 , -0.46042977, -0.46034421, -0.46034239,\n",
       "        -0.46034146, -0.46034144, -0.46034143, -0.46034143]),\n",
       " 'split1_test_score': array([-0.69314718, -0.65486716, -0.66975367, -0.58329215, -0.55283295,\n",
       "        -0.55993773, -0.56218104, -0.56362801, -0.56445099, -0.56461896,\n",
       "        -0.5647117 , -0.56472909, -0.56473105, -0.56474023]),\n",
       " 'split1_train_score': array([-0.69314718, -0.6325458 , -0.65073919, -0.51086732, -0.46599316,\n",
       "        -0.4582308 , -0.45427745, -0.45413383, -0.45406327, -0.45406176,\n",
       "        -0.45406099, -0.45406098, -0.45406097, -0.45406097]),\n",
       " 'split2_test_score': array([-0.69314718, -0.6435496 , -0.66794476, -0.54499637, -0.51936062,\n",
       "        -0.51409822, -0.51934297, -0.51840887, -0.51963423, -0.5195464 ,\n",
       "        -0.51966896, -0.51967246, -0.51968046, -0.5196852 ]),\n",
       " 'split2_train_score': array([-0.69314718, -0.63779674, -0.66259142, -0.52105191, -0.47412735,\n",
       "        -0.46833125, -0.46437933, -0.46425158, -0.46418162, -0.46418031,\n",
       "        -0.46417956, -0.46417954, -0.46417954, -0.46417954]),\n",
       " 'split3_test_score': array([-0.69314718, -0.63443192, -0.67439511, -0.50862415, -0.46344069,\n",
       "        -0.44498811, -0.43798023, -0.43573494, -0.43510538, -0.4349019 ,\n",
       "        -0.43484178, -0.43482103, -0.43481408, -0.43481297]),\n",
       " 'split3_train_score': array([-0.69314718, -0.64330596, -0.67737742, -0.53640233, -0.49462262,\n",
       "        -0.49001276, -0.48688143, -0.48669656, -0.48664287, -0.48664094,\n",
       "        -0.48664036, -0.48664035, -0.48664034, -0.48664034]),\n",
       " 'split4_test_score': array([-0.69314718, -0.63360253, -0.68717203, -0.50099851, -0.44054264,\n",
       "        -0.43658358, -0.42938181, -0.42967303, -0.42918469, -0.429227  ,\n",
       "        -0.42918178, -0.42918718, -0.42918361, -0.42918326]),\n",
       " 'split4_train_score': array([-0.69314718, -0.64355307, -0.68929319, -0.53767349, -0.4960373 ,\n",
       "        -0.48940547, -0.48587708, -0.48574589, -0.48568443, -0.48568307,\n",
       "        -0.48568241, -0.48568239, -0.48568239, -0.48568239]),\n",
       " 'std_fit_time': array([  2.03100614e-04,   2.26322337e-04,   5.82545783e-04,\n",
       "          8.74070736e-05,   1.06134718e-04,   1.91155423e-04,\n",
       "          3.18872755e-04,   4.15809111e-05,   1.20700436e-04,\n",
       "          1.45257904e-04,   1.35518211e-04,   2.53439169e-04,\n",
       "          2.98606888e-04,   1.22848060e-04]),\n",
       " 'std_score_time': array([  9.81409329e-04,   4.76529485e-04,   7.35910682e-05,\n",
       "          2.00890165e-04,   2.39752851e-05,   2.10603130e-04,\n",
       "          1.01351960e-04,   1.49072566e-04,   4.38537260e-05,\n",
       "          9.58166747e-05,   1.66602358e-04,   3.37657897e-04,\n",
       "          5.91965656e-04,   3.53120611e-04]),\n",
       " 'std_test_score': array([ 0.        ,  0.0077027 ,  0.00705678,  0.02928233,  0.04020229,\n",
       "         0.04676272,  0.05208892,  0.05314666,  0.05399652,  0.05410539,\n",
       "         0.05419418,  0.05420678,  0.05421233,  0.05421698]),\n",
       " 'std_train_score': array([ 0.        ,  0.0040502 ,  0.01307421,  0.01015154,  0.01221596,\n",
       "         0.01305228,  0.01344027,  0.01343697,  0.01344534,  0.0134453 ,\n",
       "         0.01344539,  0.01344539,  0.01344539,  0.01344539])}"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 查看结果\n",
    "grid.cv_results_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.494457683412\n",
      "{'C': 0.1, 'penalty': 'l2'}\n"
     ]
    }
   ],
   "source": [
    "# examine the best model\n",
    "print(-grid.best_score_)\n",
    "print(grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('mean_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n",
      "/Users/karen/anaconda3/lib/python3.6/site-packages/sklearn/utils/deprecation.py:122: FutureWarning: You are accessing a training score ('std_train_score'), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True\n",
      "  warnings.warn(*warn_args, **warn_kwargs)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\nLwwUSVIvXgFxb574/ORqvAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1a164604e0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot CV误差曲线\n",
    "test_means = grid.cv_results_[ 'mean_test_score' ]\n",
    "test_stds = grid.cv_results_[ 'std_test_score' ]\n",
    "train_means = grid.cv_results_[ 'mean_train_score' ]\n",
    "train_stds = grid.cv_results_[ 'std_train_score' ]\n",
    "\n",
    "\n",
    "# plot results\n",
    "n_Cs = len(Cs)\n",
    "number_penaltys = len(penaltys)\n",
    "test_scores = np.array(test_means).reshape(n_Cs,number_penaltys)\n",
    "train_scores = np.array(train_means).reshape(n_Cs,number_penaltys)\n",
    "test_stds = np.array(test_stds).reshape(n_Cs,number_penaltys)\n",
    "train_stds = np.array(train_stds).reshape(n_Cs,number_penaltys)\n",
    "\n",
    "x_axis = np.log10(Cs)\n",
    "for i, value in enumerate(penaltys):\n",
    "    #pyplot.plot(log(Cs), test_scores[i], label= 'penalty:'   + str(value))\n",
    "    pyplot.errorbar(x_axis, test_scores[:,i], yerr=test_stds[:,i] ,label = penaltys[i] +' Test')\n",
    "    pyplot.errorbar(x_axis, train_scores[:,i], yerr=train_stds[:,i] ,label = penaltys[i] +' Train')\n",
    "    \n",
    "pyplot.legend()\n",
    "pyplot.xlabel( 'log(C)' )                                                                                                      \n",
    "pyplot.ylabel( 'neg-logloss' )\n",
    "pyplot.savefig('LogisticGridSearchCV_C.png' )\n",
    "\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "从模型结果来看，最佳正则函数为L2，正则参数C为0.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
